#ifndef __select_hpp__
#define __select_hpp__

#include <croco/os/native_handle_type.hpp>
#include <set>

namespace croco
{
namespace os
{

class select_timeout
{
public:
    enum { infinite = -1 };
    enum UNIT { SEC, MS };
    template<UNIT>
    struct timeout_value
    {
        explicit timeout_value(int v) : value(v) {}
        int value;
    };
    typedef timeout_value<SEC> second;
    typedef timeout_value<MS> milisecond;

    select_timeout() : m_ms(infinite) {}
    select_timeout(second ts);
    select_timeout(milisecond tms);

    int value() const { return m_ms; }

private:
    int m_ms;
};

struct select_fds
{
    select_fds& add_read(native_handle_type handle);
    select_fds& add_write(native_handle_type handle);
    select_fds& add_interrupt(native_handle_type handle);
    bool interrupted(const std::set<native_handle_type>& signaled) const;

    std::set<native_handle_type> read;
    std::set<native_handle_type> write;
    std::set<native_handle_type> interrupt;
};

std::set<native_handle_type> do_select(const select_fds& descriptors, select_timeout timeout = select_timeout());

} // namespace os
} // namespace croco

#endif // __select_hpp__
